package com.xxcxcxcx.xc_moremob.common.entities.common_mob.forestmob.farm_zombie;

import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.*;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.animal.IronGolem;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.monster.ZombifiedPiglin;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
import software.bernie.geckolib3.core.controller.AnimationController;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;

import javax.annotation.Nullable;

public class FarmZombieEntity extends Monster implements IAnimatable{
    //定义一个动画事件处理器
    private AnimationFactory factory = new AnimationFactory(this);
    public boolean IsBabyMelee;
    public boolean playAttackAnimation = false;
    public int attackTick=1;
    //枚举攻击状态
    public static final EntityDataAccessor<Integer> STATE = SynchedEntityData.defineId(FarmZombieEntity.class, EntityDataSerializers.INT);
    //打破大门的可能

    public FarmZombieEntity(EntityType<? extends Monster> type, Level worldIn) {
        super(type, worldIn);
        this.xpReward = 15;
        this.setBaby(worldIn.getRandom().nextFloat()<0.05F);
    }

    protected void registerGoals() {
        this.goalSelector.addGoal(1, new FarmZombieEntity.AttackGoal(this, 1.0D, false));
        this.goalSelector.addGoal(6, new FloatGoal(this));
        this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1d));
        this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F));
        this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
        this.targetSelector.addGoal(1, (new HurtByTargetGoal(this)).setAlertOthers(ZombifiedPiglin.class));
        this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
        this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false));
        this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
    }

    public static AttributeSupplier.Builder prepareAttributes() {
        return Monster.createMonsterAttributes()
                .add(Attributes.MAX_HEALTH, 30).
                add(Attributes.MOVEMENT_SPEED, (double)0.2F).
                add(Attributes.ATTACK_DAMAGE, 4.0D);
    }
    //伤害函数
    public boolean doHurtTarget(Entity entityIn) {
        boolean flag = super.doHurtTarget(entityIn);
        if (flag) {
            if(entityIn instanceof LivingEntity livingEntity){
                livingEntity.addEffect(new MobEffectInstance(MobEffects.BLINDNESS,50,0),this);
            }
        }
        if(!flag)this.playAttackAnimation=false;
        return flag;
    }
    //该状态播放器控制生物平时的各种动作
    private <E extends IAnimatable> PlayState predicatebase(AnimationEvent<E> event) {
        //不动的话就播放闲置时的动画
        event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.model.base", true));
        return PlayState.CONTINUE;
    }
    private <E extends IAnimatable> PlayState predicatemove(AnimationEvent<E> event) {
        //生物在移动，就播放移动的动画，路径和第2步的动作字符串对应
        if (event.isMoving()) {
            event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.model.move", true));
            return PlayState.CONTINUE;
        }
        return PlayState.STOP;
    }
    //该状态播放器控制生物攻击时的各种动作
    private <E extends IAnimatable> PlayState predicateatk(AnimationEvent<E> event) {
        //如果生物攻击状态为1并且没有死亡，就执行这个攻击动画

         if (this.getAttckingState()== 1 && !(this.dead || this.getHealth() < 0.01 || this.isDeadOrDying())) {
            event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.model.atk1", false));
         }
        return PlayState.CONTINUE;
    }
    //将我们之前的所有动画控制器进行注册
    @Override
    public void registerControllers(AnimationData data) {
        data.addAnimationController(new AnimationController(this, "farmzombiebase",
                10, this::predicatebase));
        data.addAnimationController(new AnimationController(this, "farmzombiemove",
                10, this::predicatemove));
//        data.addAnimationController(new AnimationController(this, "farmzombieatk",
//                0, this::predicateatk));
    }

    @Override
    public AnimationFactory getFactory() {
        // TODO Auto-generated method stub
        return this.factory;
    }

    //生物实体声音
    @Nullable
    protected SoundEvent getAmbientSound() {
        return SoundEvents.ZOMBIE_AMBIENT;
    }

    protected SoundEvent getHurtSound(DamageSource source) {
        return SoundEvents.ZOMBIE_HURT;
    }

    protected SoundEvent getDeathSound() {
        return SoundEvents.ZOMBIE_DEATH;
    }

    protected void playStepSound(BlockPos pos, BlockState blockstate) {
        this.playSound(SoundEvents.ZOMBIE_STEP, 0.15F, 1.0F);
    }

    //怪物能不能破门而入

    public void addAdditionalSaveData(CompoundTag p_34319_) {
        super.addAdditionalSaveData(p_34319_);
        p_34319_.putBoolean("IsBaby", this.isBaby());
    }

    public void readAdditionalSaveData(CompoundTag p_34305_) {
        super.readAdditionalSaveData(p_34305_);
        this.setBaby(p_34305_.getBoolean("IsBaby"));
    }
    public boolean isBaby() {
        return IsBabyMelee;
    }
    public void setBaby(boolean a){
        IsBabyMelee=a;
    }
    public int getAttckingState() {
        return this.entityData.get(STATE);
    }
    public void setAttackingState(int time) {
        this.entityData.set(STATE, time);
    }

    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.define(STATE, 0);
    }

    //我们生物的AI，决定使用哪种攻击方式
    static class AttackGoal extends MeleeAttackGoal {
        private final FarmZombieEntity parentEntity;
        //攻击计时器
        protected int raiseArmTicks = 0;

        public AttackGoal(FarmZombieEntity p_26019_, double p_26020_, boolean p_26021_) {
            super(p_26019_, p_26020_, p_26021_);
            this.parentEntity = p_26019_;
        }
        public void start() {
            super.start();
            parentEntity.setAttackingState(1);
            this.raiseArmTicks = 0;
        }

        public void stop() {
            super.stop();
            parentEntity.setAttackingState(0);
            this.parentEntity.setAggressive(false);
        }

        public void tick() {
            super.tick();
        }
    }
}